home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 034a / twview82.zip / VIEW.INC < prev    next >
Text File  |  1991-01-24  |  11KB  |  393 lines

  1.  
  2. procedure View;
  3. var
  4.   Grid      : screen;
  5.   OnScreen  : SectorToScreen;
  6.   XDim      : XIndex;
  7.   XLength   : integer;
  8.   YDim      : YIndex;
  9.   YLength   : integer;
  10.  
  11. function xpixel( i,j : integer ) : integer;
  12. begin
  13.   if not odd( j ) then
  14.     xpixel := (2 * i - 1) * XLength
  15.   else
  16.     xpixel := 2 * i * XLength;
  17. end;
  18.  
  19. function ypixel( i,j : integer ) : integer;
  20. begin
  21.   ypixel := (2 * j - 1) * Ylength + 4;
  22. end;
  23.  
  24. function NumVal( n : integer ) : string;
  25. var
  26.   temp : string;
  27. begin
  28.   temp := '';
  29.   while n > 0 do
  30.     begin
  31.       temp := chr( n mod 10 + ord('0') ) + temp;
  32.       n := n div 10;
  33.     end;
  34.   if length( temp ) = 1 then
  35.     temp := ' ' + temp + ' '
  36.   else if length( temp ) = 2 then
  37.     temp := ' ' + temp;
  38.   NumVal := temp;
  39. end; {NumVal}
  40.  
  41. procedure Tag( var STS : sectorToScreen;
  42.                var scr : screen;
  43.                    num : sector;
  44.                   irow : XIndex;
  45.                   jcol : YIndex );
  46. { put sector num into screen scr at irow, jcol; update sts accordingly }
  47. begin
  48.   if sts[ num].visible then
  49.     writeln('sector ', num, ' already placed before Tag!')
  50.   else if scr[ irow, jcol ].sectorNum <> 0 then
  51.     writeln('row ', irow, ', col ', jcol, ' already in use!')
  52.   else
  53.     begin
  54.       with STS[ num ] do
  55.         begin
  56.           visible := true;
  57.           row     := irow;
  58.           col     := jcol;
  59.         end; {with}
  60.       scr[ irow, jcol ].SectorNum := num;
  61.     end; {else}
  62. end; {tag}
  63.  
  64. procedure CheckOffspring( var P : Queue; where : sector; maxDist : integer);
  65. { Check all sectors from "where" to see if they should be pushed
  66. onto the Queue }
  67. var
  68.   t : warpIndex;
  69. begin
  70.   with space.sectors[ where ] do
  71.     if number > 0 then
  72.       for t := 1 to number do
  73.         if (not OnScreen[ data[ t ] ].visible) and
  74.            (Distances[ data[t] ].d <= maxDist)    then
  75.           enqueue( P, where, data[ t ] );
  76. end; {check offspring}
  77.  
  78. procedure GoDirection( d : integer;
  79.                    var Row   : XIndex;
  80.                    var Col   : YIndex);
  81. { 0 is upleft, 1 left, 2 downleft, 3 downright, etc mod 6 }
  82. begin
  83.   d := abs( d ) mod 6;
  84.   if odd( Col ) then
  85.     case d of
  86.       0 : begin
  87.             if Col > 1 then col := col - 1;
  88.             if Row < XDim then row := row + 1;
  89.           end;
  90.       1 : if Row < XDim then row := row + 1;
  91.       2 : begin
  92.             if Col < YDim then col := col + 1;
  93.             if Row < XDim then row := row + 1;
  94.           end;
  95.       3 : if Col < YDim then col := col + 1;
  96.       4 : if row > 1 then row := row - 1;
  97.       5 : if Col > 1 then col := col - 1;
  98.     end {case}
  99.   else
  100.     case d of
  101.     0 : if Col > 1 then col := col - 1;
  102.     1 : if Row < XDim then row := row + 1;
  103.     2 : if Col < YDim then col := col + 1;
  104.     3 : begin
  105.           if Col < YDim then col := col + 1;
  106.           if Row > 1 then row := row - 1;
  107.         end;
  108.     4 : if Row > 1 then row := row - 1;
  109.     5 : begin
  110.           if Col > 1 then col := col - 1;
  111.           if Row > 1 then row := row - 1;
  112.         end;
  113.     end; {case}
  114. end;
  115.  
  116. procedure seek( var freerow : Xindex; var freecol : Yindex; home : sector );
  117. const
  118.   MaxTries = 100;
  119. var
  120.   one, two, three, n : integer;
  121. { Trying to find a home for the new guy, close to the home sector.
  122. one, two, and three will be random directions to try (of radius 1, 2, and
  123. 3).  When we are successful, we just break out of the procedure, hopefully
  124. returning a freerow and freecol. }
  125. begin
  126.   one := die( 6 );
  127.   for one := one to one + 5 do { from random start, advance 5 positions }
  128.     begin
  129.       freerow := OnScreen[ home ].row;
  130.       freecol := OnScreen[ home ].col;
  131.       GoDirection( one, freerow, freecol );
  132.       if grid[ freerow, freecol ].SectorNum = 0 then
  133.         exit;
  134.     end; {one}
  135.   one := die( 6 );
  136.   two := die( 6 );
  137.   for one := one to one + 5 do
  138.     for two := two to two + 5 do
  139.       begin
  140.         freerow := OnScreen[ home ].row;
  141.         freecol := OnScreen[ home ].col;
  142.         GoDirection( one, freerow, freecol );
  143.         GoDirection( two, freerow, freecol );
  144.         if grid[ freerow, freecol ].SectorNum = 0 then
  145.           exit;
  146.       end; {one two}
  147.   one := die( 6 );
  148.   two := die( 6 );
  149.   three := die( 6 );
  150.   for one := one to one + 5 do
  151.     for two := two to two + 5 do
  152.       for three := three to three + 5 do
  153.         begin
  154.           freerow := OnScreen[ home ].row;
  155.           freecol := OnScreen[ home ].col;
  156.           GoDirection( one, freerow, freecol );
  157.           GoDirection( two, freerow, freecol );
  158.           GoDirection( three, freerow, freecol );
  159.           if grid[ freerow, freecol ].SectorNum = 0 then
  160.             exit;
  161.         end; {one two three}
  162.   writeln('couldn''t place anything near ', home );
  163.   n := 0;
  164.   repeat
  165.     freerow := die( xdim );
  166.     freecol := die( ydim );
  167.     n := n + 1;
  168.   until (n = MaxTries) or (grid[ freerow, freecol ].sectorNum = 0);
  169. end; {seek}
  170.  
  171. procedure FindHome( var Grid : screen;
  172.                     var Showing : SectorToScreen;
  173.                         home, near : sector );
  174. { This is an interesting bit: given the home sector, find an open slot
  175. in the Grid to place the near sector. }
  176. var
  177.   basedir : integer;
  178.   baserow : XIndex;
  179.   basecol : YIndex;
  180. begin
  181. {  writeln('Trying to find a home for ', near, ' close to ', home );
  182.   writeln('starting at ', showing[ home ].row, showing[ home ].col ); }
  183.   seek( baserow, basecol, home );
  184.   if grid[ baserow, basecol ].SectorNum <> 0 then
  185.     writeln('Seek Failed!')
  186.   else
  187.     Tag( Showing, Grid, near, baserow, basecol );
  188. {  writeln('chose ', baserow, ' ', basecol );
  189.   readln; }
  190. end;
  191.  
  192. procedure PlaceSectors( var Grid  : screen;
  193.                         var Showing : SectorToScreen;
  194.                         var maxDist : integer;
  195.                         var BaseSect : sector );
  196. var
  197.   PlaceMe : Queue;
  198.   daddy, sonny : sector;
  199. begin
  200.   Tag( showing, Grid, baseSect, XDim div 2, YDim div 2 ); { put first in center}
  201.   PlaceMe.front := 0;
  202.   CheckOffspring( PlaceMe, baseSect, maxdist );
  203.   While PlaceMe.front <> 0 do
  204.     begin
  205.       serve( PlaceMe, daddy, sonny );
  206.       if not showing[ sonny ].visible then
  207.         begin
  208.           FindHome( Grid, Showing, daddy, sonny );
  209.           if Showing[ sonny ].visible then             { if he didn't make it}
  210.             CheckOffspring( PlaceMe, sonny, maxDist ); { don't look for kids }
  211.         end;{if not showing}
  212.     end; {while}
  213. end; {while}
  214.  
  215. procedure InitSectorToScreen( var s : SectorToScreen );
  216. var
  217.   n : sector;
  218. begin
  219.   for n := 1 to 1000 do
  220.     s[ n ].visible := false;
  221. end;
  222.  
  223. procedure InitScreen( var s : Screen );
  224. var
  225.   r : XIndex;
  226.   c : YIndex;
  227. begin
  228.   for r := 1 to XDim do for c := 1 to YDim do
  229.     s[ r, c ].sectorNum := 0;
  230. end;
  231.  
  232. procedure FillGrid( var Grid : screen;
  233.                     var Showing : SectorToScreen;
  234.                     var Distances : distanceArray );
  235. { Choose a sector, and fill Distances with distance to that sector,
  236. as well as Showing and Grid based on nearby vertices. }
  237. var
  238.   maxD : integer;
  239.   sn   : sector;
  240.   ch   : char;
  241. begin
  242.   repeat
  243.     write('Starting at which sector? ');
  244.     readln( sn );
  245.     if space.sectors[ sn ].number = 0 then
  246.       writeln('You have never visited ', sn );
  247.   until space.sectors[ sn ].number > 0;
  248.   FixDistances( sn, Distances );
  249.   repeat
  250.     write( 'Max distance to include? ');
  251.     readln( maxD );
  252.     writeln( 'Total of ', CountDist( maxD), ' at distance at most ', MaxD );
  253.     write('Is this okay?  (y/n) ');
  254.     readln( ch );
  255.   until ch in ['Y','y'];
  256.   InitSectorToScreen( Showing );
  257.   InitScreen( Grid );
  258.   PlaceSectors( Grid, Showing, maxD, sn );
  259. end; {FillGrid}
  260.  
  261.  
  262.  
  263. procedure CircleSector( x : XIndex; y : YIndex; s : sector );
  264. const
  265.   size = 11;
  266. var
  267.   r, c, n : integer;
  268.   q    : rect;
  269. begin
  270.   r := xpixel( x, y );
  271.   c := ypixel( x, y );
  272.   SetRect( q, r - size, c - size, r + size, c + size );
  273.   eraseOval( q );
  274.   with space.sectors[ s ] do
  275.     if number > 0 then
  276.       if portType <> NotAPort then
  277.         FrameRect( q )
  278.       else
  279.         FrameOval( q );
  280.   MoveTo( r - xoffset, c - yoffset );
  281.   Drawstring( NumVal( s ) );
  282. end;
  283.  
  284. procedure NormalPenStats;
  285. begin
  286.   PenSize( 1, 1 );
  287. end;
  288.  
  289. procedure UnknownPenStats;
  290. begin
  291.   Pensize( 3, 3 );
  292. {  PenPat( ltGray ); }
  293. end;
  294.  
  295. procedure ConnectVertices( i1, i2 : XIndex; j1, j2 : YIndex;
  296.                            TwoWay : boolean );
  297. var
  298.   x1, y1, x2, y2 : integer;
  299. begin
  300.   x1 := xpixel( i1, j1 );
  301.   y1 := ypixel( i1, j1 );
  302.   x2 := xpixel( i2, j2 );
  303.   y2 := ypixel( i2, j2 );
  304.   if TwoWay then
  305.     NormalPenStats
  306.   else
  307.     UnknownPenStats;
  308.   MoveTo( x1, y1 );
  309.   LineTo( x2, y2 );
  310. end;
  311.  
  312. procedure DrawGrid( var G : screen; STS : SectorToScreen );
  313. var
  314.   i : XIndex;
  315.   j : YIndex;
  316.   t : WarpIndex;
  317.   temp : integer;
  318. begin
  319.   clearScreen;
  320.   for i := 1 to XDim do
  321.     for j := 1 to YDim do
  322.       if G[ i, j ].sectorNum <> 0 then
  323.         with G[ i, j ] do
  324.           with space.sectors[ sectorNum ] do if number > 0 then
  325.             for t := 1 to number do
  326.               if STS[ data[ t ] ].visible then
  327.                 ConnectVertices( i, STS[data[t] ].row, j, STS[data[t]].col,
  328.                                  IsWarp( data[t], sectorNum ) );
  329.   NormalPenStats; 
  330.   for i := 1 to XDim do
  331.     for j := 1 to YDim do
  332.       if G[ i, j ].sectorNum <> 0 then
  333.           CircleSector( i, j, G[i,j].sectorNum );
  334. end;
  335.  
  336. procedure GetDimensions( var x : XIndex; var xl : integer;
  337.                          var y : YIndex; var yl : integer );
  338. var
  339.   line : string;
  340.   ok   : boolean;
  341.   tempx, tempy,
  342.   position : integer;
  343. begin
  344.   ok := false;
  345.   repeat
  346.     write('Max dimensions? [', XDimMax, ' by ', YDimMax, ']  ');
  347.     readln( line );
  348.     if line = '' then
  349.       begin
  350.         ok := true;
  351.         x := XDimMax * 2 div 3;
  352.         y := YDimMax * 2 div 3;
  353.       end
  354.     else
  355.       begin
  356.         position := 1;
  357.         tempx := 0;
  358.         while (position <= length( line )) and
  359.               (line[position] in ['0'..'9']) do
  360.           begin
  361.             tempx := 10 * tempx + ord( line[ position ] ) - ord( '0' );
  362.             position := position + 1;
  363.           end; {while}
  364.         position := position + 1;
  365.         while (position <= length( line ) ) and
  366.               (line[position] in [' ', #9, #10, #13 ]) do
  367.           position := position + 1;
  368.         tempy := 0;
  369.         while (position <= length( line )) and
  370.               (line[position] in ['0'..'9']) do
  371.           begin
  372.             tempy := 10 * tempy + ord( line[position] ) - ord('0');
  373.             position := position + 1;
  374.           end; {while}
  375.         ok := (tempx>0) and (tempx<=XDimMax) and (tempy>0) and (tempy<=YDimMax);
  376.         if ok then
  377.           begin
  378.             x := tempx;
  379.             y := tempy;
  380.           end {if}
  381.         else
  382.           begin
  383.             writeln('I don''t understand ', line );
  384.             writeln('Please give two integers separated by a space.');
  385.           end; {else}
  386.       end; {else}
  387.   until ok;
  388.   xl := trunc( XMax / x / 2 );
  389.   yl := trunc( YMax / y / 2);
  390. end;
  391.  
  392. begin {view}
  393.     GetDimensions( XDim, XLength, YDim, Ylength );